#pragma once
#include <string>
#include <cstddef> // std::size_t
#include <boost/date_time/posix_time/posix_time.hpp>
#include <odb/nullable.hxx>
#include <odb/core.hxx>

#pragma db object // 将这个类映射为数据库的表
class Student
{
public:
    Student() {}
    Student(unsigned long sn, const std::string &name, unsigned short age, unsigned long class_id) : _sn(sn), _name(name), _age(age), _classes_id(class_id) {}

    void set_sn(unsigned long num) { _sn = num; }
    unsigned long sn() { return _sn; }

    void set_name(const std::string &name) { _name = name; }
    std::string name() { return _name; }

    void set_age(unsigned short num) { _age = num; }
    odb::nullable<unsigned short> age() { return _age; }

    void set_classes_id(unsigned long class_id) { _classes_id = class_id; }
    unsigned long classes_id() { return _classes_id; }

private:
    friend class odb::access; // 设置友元

    #pragma db id auto // 设置id自增
    unsigned long _id;
    #pragma db unique // 设置学号唯一
    unsigned long _sn;
    std::string _name;
    odb::nullable<unsigned short> _age;
    #pragma db index // 将班级id设置为普通索引
    unsigned long _classes_id;
};

#pragma db object
class Classes
{
public:
    Classes() {}
    Classes(const std::string &name) : _name(name) {}
    void name(const std::string &name) { _name = name; }
    std::string name() { return _name; }

private:
    friend class odb::access;

    #pragma db id auto
    unsigned long _id;
    std::string _name;
};

// 查询所有的学生信息，并显示班级名称
//  view构建联合查询表Student和班级，再通过学生表里维护的classes_id，和classes表维护的class_id进行比对
#pragma db view object(Student) \
    object(Classes = classes : Student::_classes_id == classes::_id) query((?))
struct classes_student
{
    #pragma db column(Student::_id)
    unsigned long id;
    #pragma db column(Student::_sn)
    unsigned long sn;
    #pragma db column(Student::_name)
    std::string name;
    #pragma db column(Student::_age)
    odb::nullable<unsigned short> age;
    #pragma db column(classes::_name)
    std::string classes_name;
};

// 只查询学生姓名  ,   (?)  外部调用时传入的过滤条件
#pragma db view query("select name from Student" + (?))
struct all_name
{
    std::string name;
};

// odb -d mysql --std c++11 --generate-query --generate-schema --profile boost/date-time student.hxx